/*
 * L.TileLayer.Colorizr is a regular tilelayer with mapped colors.
 */
(function () {
    // L.TileLayer.Colorizr = 
    var Colorizr = L.TileLayer.extend({
     initialize: function (url, options) {
      options = L.extend({}, L.TileLayer.prototype.options, {
       colorize: function (pixel) {
        return pixel;
       },
       crossOrigin: 'Anonymous'
      }, options);
      L.TileLayer.prototype.initialize.call(this, url, options);
      L.setOptions(this, options);
      this.setColorizr(this.options.colorize);
      this.on('tileload', function (e) {
       this._colorize(e.tile);
      });
     },
     setColorizr: function (colorizrFactory) {
      if (!colorizrFactory || typeof colorizrFactory !== 'function') {
       throw 'The colorize option should be a function and return an object with at least one of "r", "g", "b", or "a" properties. Got:' +
       typeof colorizrFactory;
      } else {
       this.options.colorize = colorizrFactory;
      }
      this.redraw(false);
     },
     _createTile: function () {
      var tile = L.TileLayer.prototype._createTile.call(this);
      tile.crossOrigin = "Anonymous";
      return tile;
     },
     _colorize: function (img) {
      if (img.getAttribute('data-colorized')) {
       img.hidden = false;
       return;
      }else {
       img.hidden = true;
      }
      var _img = img;
      var img = new Image();
      img.crossOrigin = 'Anonymous';
      img.src = _img.src;
      var _this = this;
      img.onload = function () {
       var canvas = document.createElement("canvas");
       canvas.width = img.width;
       canvas.height = img.height;
       var ctx = canvas.getContext("2d");
       ctx.drawImage(img, 0, 0);
       var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
       var pix = imgd.data;
       for (var i = 0, n = pix.length; i < n; i += 4) {
        var pixel = _this.options.colorize({r: pix[i], g: pix[i + 1], b: pix[i + 2], a: pix[i + 3]});
        if (!!!pixel || pixel !== Object(pixel) || Object.prototype.toString.call(pixel) === '[object Array]') {
         if (i === 0) {
          throw 'The colorize option should return an object with at least one of "r", "g", "b", or "a" properties.';
         }
        } else {
         if (pixel.hasOwnProperty('r') && typeof pixel.r === 'number') {
          pix[i] = pixel.r;
         }
         if (pixel.hasOwnProperty('g')) {
          pix[i + 1] = pixel.g;
         }
         if (pixel.hasOwnProperty('b')) {
          pix[i + 2] = pixel.b;
         }
         if (pixel.hasOwnProperty('a')) {
          pix[i + 3] = pixel.a;
         }
        }
       }
       ctx.putImageData(imgd, 0, 0);
       _img.setAttribute('data-colorized', true);
       _img.src = canvas.toDataURL();
      };
     }
    });
    (function (factory, window) {
     // define an AMD module that relies on 'leaflet'
     if (typeof define === 'function' && define.amd) {
      define(['leaflet'], factory);
      // define a Common JS module that relies on 'leaflet'
     } else if (typeof exports === 'object') {
      module.exports = factory(require('leaflet'));
     }
     // attach your plugin to the global 'L' variable
     if (typeof window !== 'undefined' && window.L) {
      window.L.tileLayer.colorizr = factory(L);
     }
    }(function (L) {
     return function (url, options) {
      return new Colorizr(url, options);
     };
    }, window));
   })()